package common

/**
用户验证拦截器
*/
import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"strconv"
	"time"
)

type UserClaims struct {
	Username string `json:"username"`
	Ip string `json:"ip"`
	jwt.StandardClaims
}

// CreateLoginToken 创建登录token
func CreateLoginToken(username string) (string, error) {
	var claims = UserClaims{
		username,
		"",
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * 24 * 1).Unix(), //过期时间1天
			Issuer:    "craftsman",                               // 签发人
		},
	}

	return genToken(claims)
}

// CreateApiToken 创建api调用的token
func CreateApiToken(expiresAt *time.Time, ip string) (string, error) {

	jwt := jwt.StandardClaims {
		Issuer: "craftsman", // 签发人
	}

	if nil != expiresAt && !expiresAt.IsZero() {
		//大于0才设置超时时间
		jwt.ExpiresAt = expiresAt.Unix()
	}

	var claims = UserClaims {
		strconv.FormatInt(time.Now().Unix(), 10),
		ip,
		jwt,
	}

	return genToken(claims)
}

// 生成token
func genToken(claims UserClaims) (string, error) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err := token.SignedString([]byte(Secret))
	if err != nil {
		return "", fmt.Errorf("生成token失败:%v", err)
	}
	return signedToken, nil
}

// VerifyToken 解析token
func VerifyToken(tokenStr string) (*UserClaims, error) {
	token, err := jwt.ParseWithClaims(tokenStr, &UserClaims{}, func(token *jwt.Token) (i interface{}, err error) { // 解析token
		return Secret, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*UserClaims); ok && token.Valid { // 校验token
		return claims, nil
	}

	return nil, errors.New("认证错误")
}